package com.olap.starter.aop;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;


/**
 * @author WBG
 * @date 2020/8/26 17:15
 * @describe
 */
/*@Aspect
@Component*/
@Slf4j
public class AspectControllerLog {

    @Pointcut("execution( public * com.olap.starter.controller..*.*(..))")
    public void controllerMethod() {
    }

    /**
     * 方法执行前
     *
     * @param joinPoint
     * @throws Exception
     */
    @Before("controllerMethod()")
    public void LogRequestInfo(JoinPoint joinPoint){

        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();

            StringBuilder requestLog = new StringBuilder();
            Signature signature = joinPoint.getSignature();
            log.info("==> " + request.getMethod() + "：" + request.getRequestURI() + "(" + ((MethodSignature) signature).getMethod().getName()+")");

            // 处理请求参数
            String[] paramNames = ((MethodSignature) signature).getParameterNames();
            Object[] paramValues = joinPoint.getArgs();
            int paramLength = null == paramNames ? 0 : paramNames.length;
            if (paramLength == 0) {
                requestLog.append("==> parameter = {} ");
            } else {
                requestLog.append("==> parameter = [ ");
                for (int i = 0; i < paramLength - 1; i++) {
                    if(paramNames[i] == null){
                        continue;
                    }
                    requestLog.append(paramNames[i]).append(" = ").append(JSONObject.toJSONString(paramValues[i])).append(",");
                }
                requestLog.append(paramNames[paramLength - 1]).append(" = ").append(JSONObject.toJSONString(paramValues[paramLength - 1])).append(" ]");
            }

            log.info(requestLog.toString());
        }catch (Exception e){
            log.error(e.getMessage());
            e.printStackTrace();
        }

    }

    /**
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("controllerMethod()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = point.proceed(); //切入方法
        log.info("==> time：" + (System.currentTimeMillis() - start) + " ms");
        return result;
    }

    /**
     * 方法执行后
     *
     * @param obj
     * @throws Exception
     */
    //@AfterReturning(returning = "obj", pointcut = "controllerMethod()")
    public void doAfterReturning(Object obj) {
        log.info("<== response：" + obj);
    }

}
